import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

# =========================
# 1. 定义邻接矩阵和节点标签
# =========================
adj_matrix = np.array([
        [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
        [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
        [1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1],
        [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
])
labels = ['0','1', '2', '3', '4','5','6','7','8','9','10',
          '11','12','13','14','15','16','17','18','19','20',
          '21','22','23','24','25','26','27','28','29']

# =========================
# 2. 创建图对象
# =========================
G = nx.Graph()
G.add_nodes_from(labels)

# 添加边（根据邻接矩阵）
for i in range(len(adj_matrix)):
    for j in range(i+1, len(adj_matrix)):  # 避免重复
        if adj_matrix[i][j] == 1:
            G.add_edge(labels[i], labels[j])

# =========================
# 3. 计算各中心度指标
# =========================
# 度中心度
degree_centrality = nx.degree_centrality(G)

# 接近中心度
closeness_centrality = nx.closeness_centrality(G)

# 中介中心度
betweenness_centrality = nx.betweenness_centrality(G)

# 特征向量中心度
eigenvector_centrality = nx.eigenvector_centrality(G, max_iter=1000, tol=1e-3)

# =========================
# 4. 可视化（标注TOP5和BOTTOM5）
# =========================
plt.figure(figsize=(15, 10))
pos = nx.spring_layout(G, seed=42)  # 固定布局


def plot_centrality(centrality, title, subplot_pos):
    plt.subplot(subplot_pos)

    # 按中心度排序节点
    sorted_nodes = sorted(centrality.items(), key=lambda x: x[1], reverse=True)
    n = len(sorted_nodes)

    # 动态调整选取数量（处理小规模网络）
    k = min(5, max(1, n // 2))  # 至少选1个，最多5个
    top_nodes = [node for node, _ in sorted_nodes[:k]]
    bottom_nodes = [node for node, _ in sorted_nodes[-k:]]

    # 生成颜色列表
    node_colors = []
    for node in G.nodes():
        if node in top_nodes:
            node_colors.append('red')
        elif node in bottom_nodes:
            node_colors.append('limegreen')
        else:
            node_colors.append('skyblue')

    # 节点大小与中心度成正比
    node_size = [centrality[node] * 3000 for node in G.nodes()]

    # 绘制网络
    nx.draw_networkx(
        G, pos, node_color=node_colors, node_size=node_size,
        edge_color='gray', width=1.5, with_labels=True,
        font_size=12, font_weight='bold'
    )
    plt.title(title, fontsize=14)
    plt.text(-0.2, -0.2, "Red: Top\nGreen: Bottom",
             transform=plt.gca().transAxes, fontsize=8)

plt.rcParams['font.sans-serif'] = ['SimHei']  # 例如使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 绘制所有子图
plot_centrality(degree_centrality, "度中心度", 221)
plot_centrality(closeness_centrality, "接近中心度", 222)
plot_centrality(betweenness_centrality, "中介中心度", 223)
plot_centrality(eigenvector_centrality, "特征向量中心度", 224)

plt.tight_layout()
plt.show()


# =========================
# 5. 输出TOP5和BOTTOM5结果
# =========================
def print_extremes(centrality, name):
    sorted_nodes = sorted(centrality.items(), key=lambda x: x[1], reverse=True)
    print(f"\n{name}中心度:")
    print("Top 5:")
    for node, val in sorted_nodes[:5]:
        print(f"  {node}: {val:.4f}")
    print("\nBottom 5:")
    for node, val in sorted_nodes[-5:]:
        print(f"  {node}: {val:.4f}")


print_extremes(degree_centrality, "度")
print_extremes(closeness_centrality, "接近")
print_extremes(betweenness_centrality, "中介")
print_extremes(eigenvector_centrality, "特征向量")